import { App, Modal, Notice, Setting } from 'obsidian';
import { DocumentShareSettings, ApiResponse, Document } from './types';
import { ApiClient } from './api-client';
import DocumentSharePlugin from './main';

export class UploadModal extends Modal {
    private settings: DocumentShareSettings;
    private apiClient: ApiClient;
    private plugin: DocumentSharePlugin;
    private filePath: string; // 文件路径
    private title: string;
    private content: string;
    private enableMapping: boolean; // 是否记录文件映射并上传路径

    // 表单数据
    private formData: {
        title: string;
        isPublic: boolean;
        password: string;
        theme: string;
        expiresOption: string; // 过期选项: never, 1day, 7days, 30days, custom
        customExpiresAt: string; // 自定义过期时间
        forceCreateNew: boolean; // 强制创建新文档（不更新现有文档）
    };

    constructor(
        app: App,
        plugin: DocumentSharePlugin,
        filePath: string,
        defaultTitle: string,
        content: string,
        options?: {
            enableMapping?: boolean;
        }
    ) {
        super(app);
        this.plugin = plugin;
        this.settings = plugin.settings;
        this.apiClient = plugin.apiClient;
        this.filePath = filePath;
        this.title = defaultTitle;
        this.content = content;
        this.enableMapping = options?.enableMapping ?? true;

        // 初始化表单数据
        this.formData = {
            title: defaultTitle,
            isPublic: this.settings.defaultVisibility === 'public',
            password: this.settings.defaultPassword || '',
            theme: this.settings.defaultTheme,
            expiresOption: 'never',
            customExpiresAt: '',
            forceCreateNew: false, // 默认不强制创建新文档
        };
    }

    onOpen() {
        const { contentEl } = this;

        contentEl.empty();
        contentEl.addClass('document-share-upload-modal');

        // 检查是否已有文档映射
        const existingUuid = this.plugin.getCurrentAccountDocument(this.filePath);
        const allRecords = this.plugin.getAllAccountDocuments(this.filePath);
        const hasExistingDoc = !!existingUuid;

        // 标题
        contentEl.createEl('h2', { text: '分享文档到服务器' });

        // 显示现有文档信息（如果有）
        if (hasExistingDoc) {
            const infoDiv = contentEl.createDiv({ cls: 'document-share-info' });
            infoDiv.style.padding = '10px';
            infoDiv.style.marginBottom = '15px';
            infoDiv.style.backgroundColor = 'var(--background-secondary)';
            infoDiv.style.borderRadius = '5px';

            const infoText = infoDiv.createEl('p', {
                text: `ℹ️ 此文件已上传过（共 ${allRecords.length} 个账号）`,
            });
            infoText.style.margin = '0';
            infoText.style.fontSize = '13px';
            infoText.style.color = 'var(--text-muted)';
        }

        // 文档标题
        new Setting(contentEl)
            .setName('文档标题')
            .setDesc('分享后显示的标题')
            .addText((text) =>
                text
                    .setPlaceholder('输入文档标题')
                    .setValue(this.formData.title)
                    .onChange((value) => {
                        this.formData.title = value;
                    })
            );

        // 创建新文档选项（仅当已有文档时显示）
        if (hasExistingDoc) {
            new Setting(contentEl)
                .setName('创建新文档')
                .setDesc('勾选后将创建新文档，不会更新已有文档')
                .addToggle((toggle) =>
                    toggle
                        .setValue(this.formData.forceCreateNew)
                        .onChange((value) => {
                            this.formData.forceCreateNew = value;
                        })
                );
        }

        // 可见性
        new Setting(contentEl)
            .setName('可见性')
            .setDesc('选择文档的访问权限')
            .addDropdown((dropdown) =>
                dropdown
                    .addOption('public', '公开 - 任何人都可以访问')
                    .addOption('private', '私密 - 需要密码才能访问')
                    .setValue(this.formData.isPublic ? 'public' : 'private')
                    .onChange((value) => {
                        this.formData.isPublic = value === 'public';
                        this.updatePasswordField();
                    })
            );

        // 密码输入
        const passwordSetting = new Setting(contentEl)
            .setName('访问密码')
            .setDesc('私密文档需要输入密码才能查看')
            .addText((text) =>
                text
                    .setPlaceholder('输入访问密码')
                    .setValue(this.formData.password)
                    .onChange((value) => {
                        this.formData.password = value;
                    })
            );

        // 初始化密码字段可见性
        passwordSetting.settingEl.style.display = this.formData.isPublic
            ? 'none'
            : 'flex';

        // 主题选择
        new Setting(contentEl)
            .setName('显示主题')
            .setDesc('选择文档的显示主题')
            .addDropdown((dropdown) =>
                dropdown
                    .addOption('github', 'GitHub - 经典 GitHub 样式')
                    .addOption('dark', 'Dark - GitHub 深色主题')
                    .addOption('minimal', 'Minimal - 极简主义风格')
                    .addOption('notion', 'Notion - Notion 风格')
                    .addOption('obsidian', 'Obsidian - Obsidian 深色风格')
                    .setValue(this.formData.theme)
                    .onChange((value) => {
                        this.formData.theme = value;
                    })
            );

        // 过期时间选择
        new Setting(contentEl)
            .setName('过期时间')
            .setDesc('选择文档的过期时间')
            .addDropdown((dropdown) =>
                dropdown
                    .addOption('never', '永不过期')
                    .addOption('1day', '1天后过期')
                    .addOption('7days', '7天后过期')
                    .addOption('30days', '30天后过期')
                    .addOption('custom', '自定义时间')
                    .setValue(this.formData.expiresOption)
                    .onChange((value) => {
                        this.formData.expiresOption = value;
                        this.updateCustomExpiresField();
                    })
            );

        // 自定义过期时间输入
        const customExpiresSetting = new Setting(contentEl)
            .setName('自定义过期时间')
            .setDesc('格式: YYYY-MM-DD HH:mm (例: 2025-12-31 23:59)')
            .addText((text) =>
                text
                    .setPlaceholder('2025-12-31 23:59')
                    .setValue(this.formData.customExpiresAt)
                    .onChange((value) => {
                        this.formData.customExpiresAt = value;
                    })
            );

        // 初始化自定义过期时间字段可见性
        customExpiresSetting.settingEl.style.display = 'none';

        // 按钮容器
        const buttonContainer = contentEl.createDiv({
            cls: 'modal-button-container',
        });
        buttonContainer.style.marginTop = '20px';
        buttonContainer.style.display = 'flex';
        buttonContainer.style.justifyContent = 'flex-end';
        buttonContainer.style.gap = '10px';

        // 取消按钮
        const cancelButton = buttonContainer.createEl('button', {
            text: '取消',
        });
        cancelButton.addEventListener('click', () => {
            this.close();
        });

        // 上传按钮
        const uploadButton = buttonContainer.createEl('button', {
            text: '上传',
            cls: 'mod-cta',
        });
        uploadButton.addEventListener('click', () => {
            this.handleUpload();
        });
    }

    /**
     * 更新密码字段的可见性
     */
    private updatePasswordField() {
        const passwordSetting = this.contentEl.querySelector(
            '.setting-item:nth-child(4)'
        ) as HTMLElement;
        if (passwordSetting) {
            passwordSetting.style.display = this.formData.isPublic
                ? 'none'
                : 'flex';
        }
    }

    /**
     * 更新自定义过期时间字段的可见性
     */
    private updateCustomExpiresField() {
        const customExpiresSetting = this.contentEl.querySelector(
            '.setting-item:nth-child(7)'
        ) as HTMLElement;
        if (customExpiresSetting) {
            customExpiresSetting.style.display =
                this.formData.expiresOption === 'custom' ? 'flex' : 'none';
        }
    }

    /**
     * 计算过期时间
     */
    private calculateExpiresAt(): string | undefined {
        if (this.formData.expiresOption === 'never') {
            return undefined;
        }

        const now = new Date();

        switch (this.formData.expiresOption) {
            case '1day':
                now.setDate(now.getDate() + 1);
                break;
            case '7days':
                now.setDate(now.getDate() + 7);
                break;
            case '30days':
                now.setDate(now.getDate() + 30);
                break;
            case 'custom':
                // 解析自定义时间
                if (!this.formData.customExpiresAt.trim()) {
                    return undefined;
                }

                // 尝试解析 YYYY-MM-DD HH:mm 格式
                const customDate = new Date(
                    this.formData.customExpiresAt.trim()
                );
                if (isNaN(customDate.getTime())) {
                    throw new Error('无效的日期格式');
                }

                if (customDate <= new Date()) {
                    throw new Error('过期时间必须晚于当前时间');
                }

                return customDate.toISOString();
            default:
                return undefined;
        }

        return now.toISOString();
    }

    /**
     * 处理上传
     */
    private async handleUpload() {
        // 验证表单
        if (!this.formData.title.trim()) {
            new Notice('请输入文档标题');
            return;
        }

        if (!this.formData.isPublic && !this.formData.password.trim()) {
            new Notice('私密文档必须设置访问密码');
            return;
        }

        if (
            !this.formData.isPublic &&
            this.formData.password.trim().length < 4
        ) {
            new Notice('密码长度至少为 4 个字符');
            return;
        }

        // 验证自定义过期时间
        if (
            this.formData.expiresOption === 'custom' &&
            !this.formData.customExpiresAt.trim()
        ) {
            new Notice('请输入自定义过期时间');
            return;
        }

        // 显示上传中提示
        const uploadingNotice = new Notice('正在上传文档...', 0);

        try {
            // 计算过期时间
            let expiresAt: string | undefined;
            try {
                expiresAt = this.calculateExpiresAt();
            } catch (error) {
                uploadingNotice.hide();
                new Notice(`✗ ${error.message}`);
                return;
            }

            // 准备请求数据（同时上传文件在库中的路径，便于服务端按目录展示）
            const requestData = {
                title: this.formData.title.trim(),
                content: this.content,
                is_public: this.formData.isPublic,
                password: this.formData.isPublic
                    ? undefined
                    : this.formData.password.trim(),
                theme: this.formData.theme,
                expires_at: expiresAt,
                path: this.filePath.replace(/\\/g, '/'),
            };

            // 决定是更新还是创建
            const existingUuid = this.plugin.getCurrentAccountDocument(this.filePath);
            const shouldUpdate = existingUuid && !this.formData.forceCreateNew;

            let response: ApiResponse<Document>;
            let isUpdate = false;

            if (shouldUpdate) {
                // 尝试更新现有文档
                response = await this.apiClient.updateDocument(existingUuid, requestData);
                isUpdate = true;

                // 如果权限错误，自动降级为创建新文档
                if (!response.success && (response.error === 'Unauthorized' || response.message?.includes('permission'))) {
                    console.log('权限验证失败，自动创建新文档');
                    new Notice('⚠️ 无权更新原文档，将创建新文档...', 2000);
                    response = await this.apiClient.uploadDocument(requestData);
                    isUpdate = false;
                }
            } else {
                // 创建新文档
                response = await this.apiClient.uploadDocument(requestData);
                isUpdate = false;
            }

            // 隐藏上传中提示
            uploadingNotice.hide();

            if (response.success && response.data) {
                const document = response.data;
                const viewUrl = this.apiClient.getDocumentViewUrl(
                    document.uuid
                );

                // 记录文档映射
                await this.plugin.recordDocumentMapping(
                    this.filePath,
                    document.uuid,
                    document.author
                );

                // 刷新文件装饰器
                this.plugin.refreshFileDecorations();

                // 复制链接到剪贴板
                await navigator.clipboard.writeText(viewUrl);

                // 显示成功提示
                const action = isUpdate ? '更新' : '上传';
                new Notice(
                    `✓ 文档${action}成功!\n链接已复制到剪贴板\n${viewUrl}`,
                    5000
                );

                // 关闭对话框
                this.close();
            } else {
                // 显示错误信息
                const errorMsg =
                    response.message ||
                    response.error ||
                    '上传失败,请检查网络连接和配置';

                // 如果有验证错误,显示详细信息
                if (response.errors) {
                    const errorDetails = Object.entries(response.errors)
                        .map(([field, messages]) => `${field}: ${messages.join(', ')}`)
                        .join('\n');
                    new Notice(`✗ ${errorMsg}\n${errorDetails}`, 8000);
                } else {
                    new Notice(`✗ ${errorMsg}`, 5000);
                }
            }
        } catch (error) {
            uploadingNotice.hide();
            new Notice(`✗ 上传失败: ${error.message}`, 5000);
            console.error('上传文档错误:', error);
        }
    }

    onClose() {
        const { contentEl } = this;
        contentEl.empty();
    }
}
